/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rhythm.commons.validation;

import com.rhythm.base.Message;
import com.rhythm.base.Messages;
import com.rhythm.base.Pair;
import com.rhythm.commons.collections.Lists;
import java.util.List;

/**
 *
 * @author mlee
 */
public class ExceptionBuilder {

    private MessageType defaultMessageType;
    private List<Pair<MessageType, String>> exceptions = Lists.newArrayList();

    /**
     * Default constructor for  a new instance of {@code InvalidStateExceptionBuilder}.  The default
     * {@code MessageType} will be {@code MessageType.getLowestWeighted()}
     *
     */
    public ExceptionBuilder() {
        defaultMessageType = MessageType.SEVERE;
    }

    /**
     * Constructs a new instance of {@code InvalidStateExceptionBuilder} and sets its
     * default {@code MessageType} to the given parameter. 
     * 
     * @param defaultMessageType
     */
    public ExceptionBuilder(MessageType defaultMessageType) {
        this.defaultMessageType = defaultMessageType;
    }

    public boolean add(MessageType type, String message) {
        return exceptions.add(new Pair<MessageType, String>(type, message));
    }

    public void assertNotNull(Object ref, String message) {
        if (ref == null) {
            add(defaultMessageType, message);
        }
    }

    public void assertNotNull(MessageType type, Object ref, String message) {
        if (ref == null) {
            add(type, message);
        }
    }

    public void assertNotNull(MessageType type, Object ref, String message, boolean throwOnFail) throws InvalidStateException {
        assertNotNull(type, ref, message);
        trySuppress();
    }

    public void assertFalse(boolean expression, String message) {
        if (expression) {
            add(defaultMessageType, message);
        }
    }

    public void assertFalse(MessageType type, boolean expression, String message) {
        if (expression) {
            add(type, message);
        }
    }

    public void assertTrue(boolean expression, String message) {
        if (!expression) {
            add(defaultMessageType, message);
        }
    }

    public void assertTrue(MessageType type, boolean expression, String message) {
        if (!expression) {
            add(type, message);
        }
    }

    /**
     * Trys to suppress the exception.  If now messages exists in the current
     * builder no {@code InvalidStateException} will be thrown.  If messages do
     * exists in the current builder a new instance of {@code InvalidStateException} will be thrown
     * with the message.
     *
     * @throws com.rhythm.commons.validation.InvalidStateException if messages exist
     */
    public void trySuppress() throws InvalidStateException {
        trySuppress(MessageType.INFORMATION);
    }

    /**
     * Trys to suppress the exception.  If now messages exists in the current
     * builder no {@code InvalidStateException} will be thrown.  If messages do
     * exists in the current builder a new instance of {@code InvalidStateException} will be thrown
     * with the message.
     *
     * @param type
     * @throws com.rhythm.commons.validation.InvalidStateException if messages exist
     */
    public void trySuppress(MessageType type) throws InvalidStateException {

        if (!exceptions.isEmpty()) {

            Messages messages = Messages.emtpyInstance();

            int id = 1;
            for (Pair<MessageType, String> exception : exceptions) {

                if (exception.getFirst().getWeight() >= type.getWeight()) {
                    messages.add(Message.of(id, exception.getFirst().getName(), exception.getSecond()));
                }

                id++;
            }

            throw new InvalidStateException(messages);

        }

    }
}
